home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ada / gwuada_9.zip / RECOVER.C < prev    next >
C/C++ Source or Header  |  1993-07-27  |  18KB  |  756 lines

  1. /*
  2.  * Copyright (C) 1985-1992  New York University
  3.  * 
  4.  * This file is part of the Ada/Ed-C system.  See the Ada/Ed README file for
  5.  * warranty (none) and distribution info and also the GNU General Public
  6.  * License for more details.
  7.  
  8.  */
  9.  
  10. #include "hdr.h"
  11. #include "ada.h"
  12. #include "miscp.h"
  13. #include "prsutilp.h"
  14. #include "followp.h"
  15. #include "actionp.h"
  16. #include "lookupp.h"
  17. #include "pspansp.h"
  18. #include "adalexp.h"
  19. #include "errsp.h"
  20. #include "recoverp.h"
  21.  
  22. /*    Variables needed for scope and secondary recoveries */
  23.  
  24. extern int *open_seq;
  25. /* struct two_pool *closer_toksyms;
  26.  struct two_pool *closer_bottom; */
  27. extern int n_open_seq;
  28. extern int n_closer_toksyms;
  29. extern int nps;
  30.  
  31. extern struct two_pool *closer_toksyms;
  32. extern char *CLOSER_MESSAGE_SYMS();
  33. extern char closer_candidates[13][3][5];
  34.  
  35. #define EQ(s, t) (strcmp(s, t) == 0)
  36.  
  37. char *err_message(int k, struct prsstack *curtok)        /*;err_message*/
  38. {
  39.     /*    Form error message for secondary recovery
  40.      *  The parameter 'k' indicates the point in the parse and state stacks
  41.      *  at which the recovery is being made
  42.      */
  43.  
  44.     char *e_m_s,
  45.     *err_mess;
  46.     /* k is index into state stack (not parse stack because it is off by 1) */
  47.     int pp = stack_size(sta_stack) - k;
  48.     struct prsstack *prs_stack_k = prs_stack;
  49.  
  50.     if (k == 1)
  51.         /* this is case where there is 1 element on the state stack and 
  52.           * the parse stack is empty (i.e. all input is rejected)
  53.           */
  54.         return ("Unexpected input");
  55.  
  56.     while (--pp >= 0)
  57.         prs_stack_k = prs_stack_k-> prev;
  58.  
  59.     if (EQ((err_mess = err_msg_syms(prs_stack_k->symbol)) , "")) {
  60.         int act;
  61.         struct two_pool *sta_stack_k = sta_stack;
  62.         int kk = stack_size(sta_stack) - k;
  63.  
  64.         while (--kk >= 0)
  65.             sta_stack_k = sta_stack_k -> link;
  66.  
  67.         act = action((int)(sta_stack_k->val.state), curtok->symbol);
  68.  
  69.         if (act > NUM_STATES) {
  70.             e_m_s = err_msg_syms(lhs[act - NUM_STATES - 1]);
  71.             return(EQ(e_m_s , "") ? "Unexpected input" : e_m_s);
  72.         }
  73.         else
  74.             return ("Unexpected input");
  75.  
  76.     }
  77.     else
  78.         return (err_mess);
  79. }
  80.  
  81.  
  82. int prs_block(struct two_pool *states, struct two_pool *toks)    /*;prs_block*/
  83. {
  84.     /* This parse checker returns true if the parse blocks and false  if
  85.      * it  does  not  or  if it cannot be determined that it will block.
  86.      * The sequence of states need not be complete, so  it    is  possible
  87.      * for    a  reduction  to use up all the states.     This makes the goto
  88.      * undetermined.  In such a case the FOLLOW set for  the  left    hand
  89.      * side     is  used.  If the next token is not in the follow set, then
  90.      * surely the parse must block eventually, but if it is not, we have
  91.      * to conclude that not blocking is possible.  The value returned is
  92.      * the predicate 'the parse must block if the state  stack  contains
  93.      * states as a suffix and the token sequence contains toks as a pre-
  94.      * fix'.
  95.      */
  96.     int act, red, nolh, n;
  97.     int ts;
  98.     struct two_pool *top_tp;
  99.     struct two_pool *tmp_tp;
  100.     int    cs;
  101.     short    n_states = 1;
  102.  
  103.     ts = toks->val.state;        /* ts frome toks */
  104.     toks = toks->link;
  105.  
  106.     cs = states->val.state;    /* cs = top(states) */
  107.  
  108.     while(1) {    /* while true */
  109.  
  110.         act = action(cs, ts);
  111.  
  112.         if (act == 0)
  113.             return 1;                            /* parse error */
  114.         else if (act < NUM_STATES) {        /* shift action */
  115.             if (toks == (struct two_pool *)0)
  116.                 return 0;
  117.  
  118.             /* tmp_tp = toks; destroys prs_toks!! */    /* for re-use */
  119.             ts = toks->val.state;        /* next token */
  120.             toks = toks->link;
  121.  
  122.             tmp_tp = TALLOC();
  123.             tmp_tp->link = states;
  124.             tmp_tp->val.state = (cs = act);    /* update stateseq */
  125.             states = tmp_tp;
  126.             n_states ++;
  127.         }
  128.         else if ((red = (act - NUM_STATES )) == 0)    /* accept action */
  129.             return 0;
  130.         else {    /* reduce action */
  131.             int nn;
  132.             red --;        /* Adjust for 0 offset arrays */
  133.             nolh = lhs[red];
  134.             n = n_states - rhslen[red] + 1;
  135.             nn = rhslen[red];
  136.             if (n <= 1)
  137.                 return (is_terminal(ts) && !in_FOLLOW(nolh, ts) );
  138.             /* replace rhs states with lhs    
  139.              * states[n] = (cs = action(states(n - 1), nolh));    
  140.              */
  141.  
  142.             if (nn == 0) {
  143.                 tmp_tp = TALLOC();
  144.                 tmp_tp->link = states;
  145.                 states = tmp_tp;
  146.             }
  147.             else if (nn > 1 ) {
  148.                 top_tp = states;
  149.                 while (--nn > 1)
  150.                     states = states->link;
  151.                 tmp_tp = states;
  152.                 states = states->link;
  153.                 TFREE(top_tp, tmp_tp);
  154.             }
  155.             states->val.state = 
  156.               (cs = action((int)(states->link->val.state), nolh));
  157.             /* n_states -= nn; */
  158.             n_states -= rhslen[red] - 1;
  159.         }
  160.     }
  161. }
  162.  
  163. int prs_check(struct two_pool *stateseq, int *tokseq, int n_tokseq)
  164.                                                             /*;prs_check*/
  165. {
  166.     int ts;
  167.     int cs;
  168.     struct two_pool *top_tp;
  169.     struct two_pool *tmp_tp;
  170.     struct two_pool *temp_stateseq;
  171.     int n_temp_stateseq;
  172.     int nsh;
  173.     int red, act;
  174.  
  175.     /* This is just a parser that operates from the token sequence, tokseq.
  176.      * It returns when an error occurrs, an accept occurs, or the sequence
  177.      * of tokens is exhausted.
  178.      */
  179.  
  180.     /* n_tokseq is actually the size of tokseq - 1. It is used as an offset 
  181.      * into tokseq (which starts at zero). However, when the size of tokseq
  182.      * is desired, we use (n_tokseq + 1) 
  183.      */
  184.  
  185.     copystack(stateseq, &temp_stateseq, &n_temp_stateseq);
  186.  
  187.     nsh = 0;                /* Number of tokens shifted */
  188.  
  189.     ts = tokseq[n_tokseq];            /* Top of tokseq    */
  190.     cs = temp_stateseq->val.state;        /* Top of stateseq    */
  191.  
  192.     while(1)    /* while true */
  193.     {
  194.         act = action(cs, ts);
  195.  
  196.         if (act == 0)
  197.             return nsh;            /* parse error */
  198.         else if (act < NUM_STATES)    /* Shift action */
  199.         {
  200.             if ( (++nsh ) >= (n_tokseq + 1))    /*  up shift count */
  201.                 return nsh;    /*  gone far enough */
  202.  
  203.             ts = tokseq[n_tokseq - nsh];    /* next token */
  204.  
  205.             tmp_tp = TALLOC();    /* Update stateseq */
  206.             tmp_tp->val.state = ( cs = act);
  207.             tmp_tp->link = temp_stateseq;
  208.             temp_stateseq = tmp_tp;
  209.         }
  210.         else if ((red = (act - NUM_STATES )) == 0  ) /* accept action */
  211.             return    ((ts == EOFT_SYM) ? (n_tokseq + 1) : nsh);
  212.         else {                    /* reduce action */
  213.             int nn;
  214.             red --;        /* adjust for 0 offset arrays */
  215.             nn = rhslen[red];
  216.  
  217.             /*     replace rhs states with lhs
  218.              *
  219.              *    stateseq(nn..) := [cs := ACTION(stateseq(nn-1), nolh)];        
  220.              *
  221.              *  Since the top element will be replaced, we strip off nn - 1
  222.              *  elements and then replace the top one.
  223.              *  There are 3 cases : 
  224.              *    nn == 0 :    allocate a new top element
  225.              *            for the state stack
  226.              *    nn == 1 :    Leave the top element for
  227.              *            replacement
  228.              *    nn >  1 :    Strip nn - 1 off the stack.
  229.              *            leaving the top element for
  230.              *            replacement
  231.              */
  232.  
  233.             if ( nn == 0 ) {
  234.                 tmp_tp = TALLOC();
  235.                 tmp_tp->link = temp_stateseq;
  236.                 temp_stateseq =     tmp_tp;
  237.             }
  238.             else if (nn > 1) {
  239.                 top_tp = temp_stateseq;
  240.                 while (--nn > 1)
  241.                     temp_stateseq = temp_stateseq->link;
  242.                 tmp_tp = temp_stateseq;
  243.                 temp_stateseq = temp_stateseq->link;
  244.                 TFREE(top_tp, tmp_tp);
  245.             }
  246.  
  247.             /* Replace the top element with the GOTO    */
  248.  
  249.             temp_stateseq->val.state = 
  250.               (cs = action((int)(temp_stateseq->link->val.state), lhs[red]));
  251.         }
  252.     }
  253. }
  254.  
  255. int scope_recovery(int k, int index, int *open_seq)        /*;scope_recovery*/
  256. {
  257.     int exists = 0;
  258.     int open_loc;
  259.     struct prsstack *prstmp;
  260.     int opener;
  261.     struct two_pool *tmp_tp, *saved_tail, *closer_head, *closer_tail;
  262.     struct two_pool *STA_STACK;
  263.     int closer;
  264.     int i, closer_index;
  265.     int kk = k;
  266.     int ind;
  267.     int *tmp_toksyms;
  268.     int n_tmp_toksyms;
  269.     int prs_distance;
  270.     int check_dist;
  271.     int n_closer;
  272.  
  273.     /* The parameter 'k' indicates the portion of the state stack with
  274.      * which the parse check is to be performed. The parameter 
  275.      * 'index' indicates the portion of the parse stack to be used when
  276.      * looking for the next opener to be closed.
  277.      */
  278.  
  279.     /*
  280.      * if not exists ind in [index .. n_open_seq] 
  281.      *                | k >= open_seq(ind) then
  282.      *                        return false;
  283.      * end if;
  284.      *
  285.      *        Assume that no such ind exists. Loop through, looking for
  286.      *        one.
  287.      */
  288. #ifdef EDEBUG
  289.     if (trcopt)
  290.         fprintf(errfile, "AT PROC: scope_recovery(%d, %d, %d)\n", k, index,
  291.           *open_seq);
  292. #endif
  293.  
  294.     for ( ind = index; ind < n_open_seq; ind++ )
  295.         if ( k - 1 >= open_seq[ind]) {
  296.             /* adjust to k-1 because in C version (only), size of
  297.              * parse stack is 1 less than size of state stack
  298.              */
  299.             exists = 1;
  300.             break;
  301.         }
  302.  
  303.     if (!exists)
  304.         return 0;
  305.  
  306.     open_loc = nps - open_seq[ind];
  307.  
  308.  
  309.     for (prstmp = prs_stack; open_loc--; prstmp = prstmp->prev);
  310.     opener = prstmp->symbol;
  311.     /* Keep